package com.example.ailiyuncloud.service.Impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.ailiyuncloud.dto.CommoditySkuDto;
import com.example.ailiyuncloud.mapper.CommoditySkuMapper;
import com.example.ailiyuncloud.pojo.CommodityErrorPojo;
import com.example.ailiyuncloud.pojo.Result;
import com.example.ailiyuncloud.service.CommoditySkuService;
import com.example.ailiyuncloud.vo.DeductionsCommoditySkuVO;
import com.example.ailiyuncloud.vo.QueryCommoditySkuVO;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigInteger;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: lqj
 * @Date: 2024/05/26/14:44
 * @Description:
 */
@Slf4j
@Service
public class CommoditySkuServiceImpl implements CommoditySkuService {

    public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    private static final String SKU = "SKU-";

    @Autowired
    private CommoditySkuMapper commoditySkuMapper;

    @Autowired
    private RedisTemplate<String, Object> stringRedisTemplate;


    public static String generateId() {
        // 生成标准 UUID
        UUID uuid = UUID.randomUUID();
        // 将 UUID 转换为纯数字格式
        String numericUuid = new BigInteger(uuid.toString().replaceAll("-", ""), 16).toString().substring(0, 8);
        return LocalDate.now().format(formatter) + "-" + numericUuid;
    }

    @Override
    @Transactional
    public String addCommoditySkuService(@NonNull List<CommoditySkuDto> CommoditySkuDtoList) {
        if (CommoditySkuDtoList.size() > 200) {
            throw new RuntimeException("SKU单次最多添加200条");
        }
        List<String> collect = commoditySkuMapper.selectList(Wrappers.<CommoditySkuDto>lambdaQuery()
                        .in(CommoditySkuDto::getCommodityName, CommoditySkuDtoList.stream()
                                .map(CommoditySkuDto::getCommodityName).collect(Collectors.toList()))
                        .eq(CommoditySkuDto::getDelIs, "0"))
                .stream().map(CommoditySkuDto::getCommodityName)
                .collect(Collectors.toList());

        CommoditySkuDtoList.forEach(commoditySkuPojo -> {
            String commodityName = commoditySkuPojo.getCommodityName();
            if (collect.contains(commodityName) || null == commoditySkuPojo.getSpuId()) {
                throw new RuntimeException(commoditySkuPojo.getCommodityName() + "SKU重复添加或SPUID为空，请检查数据！");
            }
            commoditySkuPojo.setSkuId(SKU + generateId());
            commoditySkuMapper.insert(commoditySkuPojo);
        });
        //sku插入最新的100条
        refreshSkuRedis();
        return "SKU添加成功";
    }

    @Override
    public IPage<CommoditySkuDto> queryCommoditySkuService(Page page, QueryCommoditySkuVO queryCommoditySkuVO) {
        IPage<CommoditySkuDto> listIPage = null;
        //判断是否查询第二页数据，如是查数据库。
        List<?> commoditySpuDTOListInfo = new ArrayList<>(16);
        if (page.getCurrent() < 1 || queryCommoditySkuVO.isEmpty()) {
            List<Object> redisCommoditySku = stringRedisTemplate.opsForList().range(SKU, 0, 10);
//            if (redisCommoditySku.size() > 0) {
//                for (Object obj : redisCommoditySku) {
//                    if (obj instanceof CommoditySkuDto) {
//                        commoditySpuDTOListInfo.add((CommoditySkuDto) obj);
//                    }
//                }
//                listIPage.setRecords(commoditySpuDTOListInfo);
//                listIPage.setCurrent(page.getCurrent());
//                listIPage.setSize(page.getSize());
//                listIPage.setTotal(100);
//                return listIPage;
//            }
        }

        listIPage = commoditySkuMapper.getCommoditySkuDTOListInfo(page, queryCommoditySkuVO);

        refreshSkuRedis();

        return listIPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String deductionsCommoditySkuService(List<DeductionsCommoditySkuVO> deductionsCommoditySkuVOList) {
        if (deductionsCommoditySkuVOList.isEmpty()) {
            throw new RuntimeException("SKU扣减接口调用失败，参数为空请检查！");
        }

        Map<String, CommoditySkuDto> collectMap = commoditySkuMapper.selectList(Wrappers.<CommoditySkuDto>lambdaQuery()
                        .in(CommoditySkuDto::getSkuId, deductionsCommoditySkuVOList.stream()
                                .map(DeductionsCommoditySkuVO::getSkuId).collect(Collectors.toList()))
                        .eq(CommoditySkuDto::getDelIs, "0"))
                .stream().collect(Collectors.toMap(CommoditySkuDto::getSkuId, o -> o));

        deductionsCommoditySkuVOList.forEach(deductionsCommoditySkuVO -> {
            String skuId = deductionsCommoditySkuVO.getSkuId();
            CommoditySkuDto commoditySkuDto = collectMap.get(skuId);
            if (ObjectUtils.isEmpty(commoditySkuDto)) {
                throw new RuntimeException("该商品不存在或已删除请检查");
            }
            Integer commoditySku = commoditySkuDto.getCommoditySku();
            Integer commodityNumber = deductionsCommoditySkuVO.getCommodityNumber();
            log.info("商品skuId：" + commoditySkuDto.getSkuId() + "商品名称：" + commoditySkuDto.getCommodityName() + "扣减前数量：" + commoditySkuDto.getCommoditySku());
            if (commodityNumber > commoditySku) {
                throw new RuntimeException(commoditySkuDto.getCommodityName() + "该商品库存不足");
            }
            Integer residueCommodityNumber = commoditySku - commodityNumber;
            commoditySkuMapper.deductionsCommoditySku(skuId, residueCommodityNumber);
        });
        return "SKU扣减成功";
    }


    public void refreshSkuRedis() {
        List<CommoditySkuDto> commoditySkuDTOList = commoditySkuMapper.getCommoditySkuDtoList(100);
        stringRedisTemplate.delete(SKU);
        stringRedisTemplate.opsForList().rightPushAll(SKU, commoditySkuDTOList);
    }

}
